
/* $Id */

#include "edilana.h"

/* 
 * Stampa in un file tutti i lemmi di "nomevocab" che sono contenuti nella
 * stringa la cui firma e' "tab" e ne restituisce il numero.
 */
int
CercaCandidate (
	int  tab[],
	char *nomevocab,
	char *nomelista,
	int  *maxl,
	int  stampa
){
char 	lemma[MAXSTRLEN];
int	tab2[NUMALFA], temp;
FILE	*invocab, *outcandi;
register int i, conta = 0;

	invocab  = IOFile(nomevocab,"r");
	outcandi = IOFile(nomelista,"w");
	if (IOFail(invocab,outcandi)) return -1;

	*maxl = 0;

	while (fgets(lemma,MAXSTRLEN,invocab) != NULL) {

		temp = strlen(lemma) - 1;

		for (i = 0; i < NUMALFA; i++) tab2[i] = 0;
		for (i = 0; i < temp; i++) tab2[lemma[i]-INIZALFA]++;

		for (i = 0; i < NUMALFA; i++)
			if (tab[i]-tab2[i] < 0) goto punto;

		if (temp > *maxl) *maxl = temp;
		fputs(lemma,outcandi);
		conta++;

		punto:;
	}

	if (stampa == ON) {
		if (conta > 0)
			printTotCandi("", conta);
		else IoDico(TROVATO_POCO);
	}

	fclose(invocab); fclose(outcandi);

return conta;
}

static int comando_esterno (
	char *comando,
	char *maschera,
	char *infile,
	char *outfile
) {
char stemp[MAXSTRLEN * 2];

	sprintf(stemp, maschera, comando, infile, outfile);
	if (system(stemp)) {
		IoDico(COMANDO_ESTERNO);
		return -1;
	}

return 0;
}

extern struct Setup *conf;

int VediCandidate (
	char *sott,
	int tab [],
	int Resto,
	int Lungh,
	int Maxls
) {
int temp = OFF;
int idx = 2;
int i = Maxls;


	/* modifica la lunghezza minima delle radici */
	if (sott[1] > '0' && sott[1] < '9')
		conf->minlenw = sott[1] - '0';

	/* vedi anche il resto per ogni candidata
	 * mostra le candidate conteneti una stringa
	 */
	else if (sott[1] == conf->comando[VEDI_CAND]) {
			if (sott[2] == '\n')
				i = Lungh + 1;
			else if (isalpha(sott[2]))
				temp = ON;
			else return COMANDO_ERRATO;
	}

	/* cerca una sequenza sul resto */
	else if (sott[1] == '0' && isalpha(sott[2])) {
		if (Resto == ON) {
			temp = ON;
			idx = 2;
			i = Lungh + 1;
		}
		else  return NON_RESTO;
	}

	/* mostra le candidate che inziano per una data stringa */
	else if (isalpha(sott[1])) {
		idx = 1;
		temp = 16;
	}

	/* mostra semplicemente le candidate */
	else if (sott[1] == '\n') ;

	/* altrimenti errore */
	else return COMANDO_ERRATO;

	StampaCol(NOMECANDI, conf->minlenw, tab, i,
		  i == (Lungh + 1), temp, &sott[idx]);

return 0;
}

int Candy (
	   char *sott,
	   char *srest,
	   int Resto,
	   int Lungh,
	   int tab[],
	   char *nomelista,
	   int *maxlen,
	   int *Maxls
) {
char 	lemma[MAXSTRLEN];


int	tab2[NUMALFA], lung, minimo;
FILE	*invocab, 
	*outcandi;

static int trascura_char = 0,
	   minlen = 0;

int i = *maxlen, idx = 1, resto = OFF, cerca = ON, stampa = 1;


	/* legge i valori di default / configfile */
	if (!trascura_char && !minlen) {
		trascura_char = conf->truncandy;
		minlen = conf->minlencandy;
	}

	/* vogliamo una stampa di variabili */
	if (sott[1] == conf->comando[VEDI_VAR] && sott[2] == '\n') {
		printf("candy: trascura %d, minlen %d%s\n",
		       trascura_char,
		       minlen,
		       conf->autofusione ? " - autofusione" : ""
		);
		return 0;
	}

	/* candidate sul resto, di cui si puo' selezionare un
	 * sottoinsieme
 	 */
	else if (sott[1] == '0') {
		cerca = OFF;
		if (!*maxlen)
			return TROVATO_POCO;
		if (Resto != ON)
			return NON_RESTO;

		if (isalpha(sott[2]))
			cerca = ON;
		else if (sott[2] == '\n')
			;
		else return COMANDO_ERRATO;

		i = StringaBase(srest, tab2);
		CercaCandidate(tab2, LemmaCandy, TEMPFILE, &lung, OFF);
		StampaCol(TEMPFILE, 1, tab2, i + 1, ON,
			  cerca , cerca ? &sott[2] : "");
		return 0;
	}

	/* seleziona le radici per stringa iniziale */
	else if (isalpha(sott[1])) cerca = 16;

	/* stampa con resto;
	 * seleziona le radici per stringa contenuta
	 */
	else if (sott[1] == *sott) {
		if (isalpha(sott[2])) {
			cerca = ON;
			idx = 2;
		}
		else if (sott[2] == '\n'){
			i = Lungh + 1;
			cerca = 0;
			resto = ON;
		}
		else if (sott[2] == *sott)
			stampa = 0;
		else return COMANDO_ERRATO;
	}
	
	/* cambia i parametri per la costruzione delle radici */
	else if (isdigit(sott[1])) {
		stampa = 0;
		trascura_char = sott[1] - '0';
		if (isdigit(sott[2]))
			minlen = sott[2] - '0';
	}

	/* fusione tra le radici di candy e quelle "standard" */
	else if (sott[1] == conf->comando[VEDI_CAND]) {
		fondi:
		if (!*maxlen)
			return TROVATO_POCO;
		IoDico(FONDO_CANDI);

		if (comando_esterno(conf->catcmd, "%s %s >>%s",
				NOMECANDI, LemmaCandy)) return -1;
		if (comando_esterno(conf->sortcmd, "%s %s >%s",
				LemmaCandy, TEMPFILE)) return -1;
		if(comando_esterno(conf->uniqcmd, "%s %s >%s",
				TEMPFILE, NOMECANDI)) return -1;

		*Maxls = *maxlen;

		return 0;
	}
	/* rivedi quanto gia' trovato */
	else if (sott[1] == '\n') {
		cerca = OFF;
		idx = 0;

	}
	else return COMANDO_ERRATO;


	if (stampa) {
		if (!*maxlen)
			return TROVATO_POCO;

		StampaCol(LemmaCandy, 1, tab, i, resto,
			  cerca, &sott[idx]);

		return 0;
	}

	invocab  = IOFile(conf->lemmario, "r");
	outcandi = IOFile(LemmaCandy, "w");
	if (IOFail(invocab, outcandi)) return -1;

	if (!minlen) minlen = 1;
	minimo = trascura_char + 1;

	while (fgets(lemma, MAXSTRLEN, invocab) != NULL) {

		lung = strlen(lemma) - 1;
		if (trascura_char && lung > minimo)
			lung -= trascura_char;
		if (lung < minlen)
			continue;

		lemma[lung] = '\0';
		
		for (i = 0; i < NUMALFA; i++) tab2[i] = 0;
		for (i = 0; i < lung; i++) tab2[lemma[i]-INIZALFA]++;

		for (i = 0; i < NUMALFA; i++)
			if (tab[i]-tab2[i] < 0) goto punto;
		
		if (lung > *maxlen) *maxlen = lung;
		lemma[lung++] = '\n';
		lemma[lung] = '\0';

		fputs(lemma, outcandi);

		punto:;
	}

	fclose(invocab);
	fclose(outcandi);

	if (trascura_char) {
		if (comando_esterno(conf->sortcmd, "%s %s >%s",
			LemmaCandy, TEMPFILE)) return -1;
		if (comando_esterno(conf->uniqcmd, "%s %s >%s",
			TEMPFILE, LemmaCandy)) return -1;
	}

	if (conf->stampacandy)
		if (*maxlen)
			StampaCol(LemmaCandy, 1, tab, *maxlen, OFF,
				  OFF, "");
		else return TROVATO_POCO;

	if (conf->autofusione)
		goto fondi;


return 0;
}

static int CharIn (char *s, char ch)
{
char *pos;
int i;

	if ((pos = strchr(s,ch)) != NULL && isalpha(s[(i = pos-s+1)]))
		return i;
	else	
		return 0;
}

void WildCandi (char *sott, char candi, char resto, int Resto)
{
char candidata[MAXSTRLEN], lemma[MAXSTRLEN], temp[MAXSTRLEN], *pos;
int  lung = 0, i, j = 0, k;	
FILE *incandi;

	if ((i = CharIn(sott,candi)) || (j = CharIn(sott,resto))) {

		if (i) strcpy(temp, NOMECANDI);
		else {
			if (Resto == OFF) {
				IoDico(NON_RESTO);
				return;
			}
			strcpy(temp, NOMERESTO);
			i = j;
		}
		if ((incandi = IOFile(temp,"r")) == NULL)
			return;

		if ((pos = strchr(sott,' ')) != NULL) {
			strcpy(temp,&sott[(k = pos-sott+1)]);
			sott[k-1] = '\0';
			lung++;
		}
		
		strcpy(lemma,&sott[i]);
		lung += strlen(lemma)-1;

		while (fgets(candidata,MAXSTRLEN,incandi) != NULL)
			if (!strncmp(candidata,lemma,lung)) {
				if (pos != NULL) {
					Stripnl(candidata);
					strcat(candidata,temp);
				}
				if (j) strcpy(sott,"[");
				else sott[i-1] = '\0';
				strcat(sott,candidata);
				break;
			}
		fclose(incandi);	
	}


return;
}
